const sayHello = (str: string): void => {
  console.log(str);
};

sayHello('abc');

let aa = sayHello('abc');

const getString = (str: string): string => {
  return str;
};

let bb = getString('abc');

// 定义布尔量
let isDone: boolean = true;

// 定义接口 一般接口的首字母要大写
interface Person {
  name: string; //确定属性
  age: number | string; //定义一个联合属性
  height?: number; //带?的是可选属性
  [propName: string]: any; //[]是任意属性
  //一旦定义了任意属性，
  // 那么确定属性和可选属性的类型都必须是它的类型的子集
  readonly id: number; //readonly定义个只读属性
}

let tom: Person = {
  name: 'tom',
  age: 12,
  id: 101
};

function getPerson(human: Person) {
  return 'human';
}

let tom1 = getPerson({ name: 'ss', age: 12, id: 123 });

// 定义数组
let ary1: number[] = [1, 2, 3];
// 联合类型的数组
let ary2: (number | string)[] = [1, 2, '2', 3];
// 泛型数组
let ary3: Array<number> = [1, 2, 3];
// 接口数组
interface NumberArray {
  [index: number]: number;
}
let ary4: NumberArray = [1, 2];
// 用any定义数组
let ary5: any[] = ['Xcat Liu', 25, { website: 'http://xcatliu.com' }];

// 定义枚举
enum Color {
  Red,
  Green,
  Blue
}
let c: Color = Color.Red;

// 函数声明（Function Declaration）
function sum(x, y) {
  return x + y;
}

// 函数表达式 这里指的是mySum（Function Expression）
let mySum = function(x, y) {
  return x + y;
};

// 定义一个函数的参数
function sum1(obj: { addNumber: string }) {
  console.log(obj);
}

// 定义空值
function info(): void {
  console.log('');
}

// 定义Never
function err(message: string): never {
  throw new Error(message);
}

// 定义Object

// 类型断言
// <>的用法
let someValue: any = 'abc';
let strLength: number = (<string>someValue).length;
// as用法
let someValue1: any = 'this is a string';
let strLength1: number = (someValue1 as string).length;

// 泛型的用法
// 接受任何类型的输入,任何类型的输出
// function getName(name: any): any {
//   return name;
// }
// 这时候输入输出不受控制,泛型的出现解决输入输出类型的统一
function getName<T>(name: T): T {
  return name;
}

let myName1 = getName(12);
let myName2 = getName('aa');
let myName3 = getName<string>('aa');
let myName4 = getName({ aa: 'abc' });
